package com.yungam.other.iot_controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.yungam.common.bean.equip.Equipment;
import com.yungam.common.bean.process.ProcessEquipment;
import com.yungam.common.bean.process.ProductProcess;
import com.yungam.common.bean.process.ProductionProcess;
import com.yungam.common.bean.product.ProductInfo;
import com.yungam.common.bean.product.ProductionBoard;
import com.yungam.common.bean.work_order.WorkOrderProduct;
import com.yungam.common.response.RetDTO;
import com.yungam.common.service.*;
import com.yungam.influxdb.service.CollectInfluxService;
import com.yungam.other.service.MesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 数控拼焊扫码结束
 */
@Slf4j
@RestController
@RequestMapping("/imcs_to_iot")
public class ProcessEndController {

    @Resource
    private EquipmentService equipmentService;
    @Resource
    private MesService mesService;
    @Resource
    private CollectInfluxService collectInfluxService;
    @Resource
    private ProductionBoardService productionBoardService;
    @Resource
    private WorkOrderProductService workOrderProductService;
    @Resource
    private ProcessEquipmentService processEquipmentService;
    @Resource
    private ProductProcessService productProcessService;
    @Resource
    private ProductionProcessService productionProcessService;
    @Resource
    private ProductInfoService productInfoService;

    @PostMapping("/processEnd")
    public RetDTO<?> processEnd(@RequestBody Map<String, Object> data) {
        log.info("========= START『iot调用imcs』[数控拼焊扫码结束]=========");
        String json = new Gson().toJson(data);
        log.info("=========『iot数据』{}", json);

        String productSn = String.valueOf(data.get("productSn")),
                ip = String.valueOf(data.get("ip"));

        Equipment equipment = equipmentService.getOne(new QueryWrapper<Equipment>().eq("equ_ip", ip));
        if (equipment == null) {
            log.error("=========『数控拼版设备不存在』=========");
            return RetDTO.error("数控拼版设备不存在");
        }
        WorkOrderProduct wop = workOrderProductService.getOne(new QueryWrapper<WorkOrderProduct>().eq("product_sn", productSn));
        if (wop == null) {
            log.error("=========『罐号不存在』=========");
            return RetDTO.error("罐号不存在");
        }
        // 根据产品号查询拼版数量
        ProductInfo productInfo = productInfoService.getOne(new QueryWrapper<ProductInfo>()
                .eq("product_no", wop.getProductNo()));
        Integer qty = productInfo.getQtyJoin();
        log.info("拼版数量为{}个", qty);

        // 根据产品代号、设备编号，判断产品工序是否存在
        List<Integer> list = processEquipmentService.list(new QueryWrapper<ProcessEquipment>()
                        .eq("equ_number", equipment.getEquNumber())).stream().map(ProcessEquipment::getProcessId)
                .collect(Collectors.toList());

        ProductProcess pp =  null;
        if (list.size() > 0) {
            pp = productProcessService.getOne(new QueryWrapper<ProductProcess>().eq("product_no", wop.getProductNo())
                    .in("process_id", list));
        }

        if (pp == null) {
            log.error("=========『设备对应工序不存在』=========");
            return RetDTO.error("设备对应工序不存在");
        }

        ProductionProcess isExist = productionProcessService.getOne(new QueryWrapper<ProductionProcess>()
                .eq("product_sn", productSn).eq("process_no", pp.getProcessNo())
                .eq("equ_no", equipment.getEquNumber()));
        if (isExist == null) {
            log.error("production_process表中罐号为{}, ip为{}的数控拼焊数据还未生成", productSn, ip);
            return RetDTO.error("production_process表该罐号的数据未生成");
        }

        // update production_process
        productionProcessService.update(new UpdateWrapper<ProductionProcess>()
                .eq("product_sn", productSn).eq("process_no", pp.getProcessNo())
                .eq("equ_no", equipment.getEquNumber())
                .set("state", 1).set("end_time", new Date()).set("good", 1));

        // 调用 mes 接口
        Map<String, Object> passData = Maps.newHashMap();
        // influxdb
        ProductionProcess cur = productionProcessService.getOne(new QueryWrapper<ProductionProcess>()
                .eq("product_sn", productSn).eq("process_no", pp.getProcessNo())
                .eq("equ_no", equipment.getEquNumber()));
        long start = cur.getStartTime().getTime() / 1000, end = cur.getEndTime().getTime() / 1000;
        Long[] range = { start, end };
        List<Map<String, Object>> collectData = collectInfluxService.getCollectData(ip, range, null);
        // board uidList
        String lastSql = "limit " + qty;
        List<String> uidList = productionBoardService.list(new QueryWrapper<ProductionBoard>()
                        .orderByDesc("end_time").last(lastSql)).stream()
                .map(ProductionBoard::getUid).collect(Collectors.toList());
        passData.put("productSn", productSn);
        passData.put("operator", Lists.newArrayList("gw002", "gw003"));         // 采集人员集合
        passData.put("equipmentNos", Lists.newArrayList(equipment.getEquNumber()));   // 设备编码集合
        passData.put("lineNo", "0101-01");                          // 产线编号
        passData.put("frNo", equipment.getFrNo());         // 工位编号
        passData.put("processNos", Lists.newArrayList(pp.getProcessNo()));       // 工序编码集合
        passData.put("toolNos", Lists.newArrayList());             // 工装集合
        passData.put("inspectionNos", Lists.newArrayList()); // 检具集合
        passData.put("uids", uidList);                   // uid 集合（板号集合）
        passData.put("panelResult", 1);               // 总检验结果 0.不合格、1.合格、2.报废
        passData.put("collectTime", new Date().getTime());      // 采集时间
        passData.put("collectData", collectData);
        log.info("调用mes接口『passStation』, 传送数据为{}", new Gson().toJson(passData));
        Map<String, Object> map = mesService.passStation(passData);
        log.info("mes接口『passStation』返回的数据为{}", new Gson().toJson(map));
        String code = String.valueOf(map.get("code"));
        if (Objects.equals(code, "0")) {
            wop.setState(1);
            workOrderProductService.updateById(wop);
        }
        log.info("给IOT发送的数据为{}", new Gson().toJson(map));
        log.info("========= END『iot调用imcs』[打磨工序结束接口] 调用成功 =========");
        return RetDTO.data(map);
    }

}
